/*
 * Copyright (c) 2025 Industrial Software Feature Database
 */
package com.comac.ins.isfd.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import com.anwen.mongo.conditions.query.LambdaQueryChainWrapper;
import com.anwen.mongo.conditions.update.LambdaUpdateChainWrapper;
import com.anwen.mongo.model.PageResult;
import com.anwen.mongo.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.comac.ins.common.core.domain.model.LoginUser;
import com.comac.ins.common.core.exception.base.BaseException;
import com.comac.ins.common.core.utils.MapstructUtils;
import com.comac.ins.common.encrypt.utils.EncryptUtils;
import com.comac.ins.common.excel.utils.ExcelUtil;
import com.comac.ins.common.mybatis.core.page.TableDataInfo;
import com.comac.ins.isfd.constant.enums.IsfdImportMethodEnum;
import com.comac.ins.isfd.domain.IsfdDatabaseDataImportRecord;
import com.comac.ins.isfd.domain.IsfdDatabaseModelConfig;
import com.comac.ins.isfd.domain.IsfdLayupSkinPropertieMongo;
import com.comac.ins.isfd.domain.bo.IsfdDatabaseDataImportRecordBo;
import com.comac.ins.isfd.domain.bo.query.IsfdLayupSkinPropertieQueryBo;
import com.comac.ins.isfd.domain.vo.IsfdBusinessDatabaseRefVo;
import com.comac.ins.isfd.domain.vo.IsfdLayupSkinPropertieMongoVo;
import com.comac.ins.isfd.mapper.IsfdBusinessDatabaseRefMapper;
import com.comac.ins.isfd.mapper.IsfdDatabaseModelConfigMapper;
import com.comac.ins.isfd.service.IIsfdDatabaseDataImportRecordService;
import com.comac.ins.isfd.service.IIsfdLayupSkinPropertieMongoService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 【请填写功能名称】Service业务层处理
 *
 * @author wujilain
 * @date 2025-05-13
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class IsfdLayupSkinPropertieMongoServiceImpl extends ServiceImpl<IsfdLayupSkinPropertieMongo> implements IIsfdLayupSkinPropertieMongoService {

    @Autowired
    private IIsfdDatabaseDataImportRecordService importRecordService;
    @Autowired
    private IsfdDatabaseModelConfigMapper isfdDatabaseModelConfigMapper;
    @Autowired
    private IsfdBusinessDatabaseRefMapper isfdBusinessDatabaseRefMapper;

    /**
     * 查询【请填写功能名称】
     *
     * @param id 主键
     * @return 【请填写功能名称】
     */
    @Override
    public IsfdLayupSkinPropertieMongoVo queryById(String id) {
        // 根据主键查询实体
        IsfdLayupSkinPropertieMongo entity = this.lambdaQuery()
            .eq(IsfdLayupSkinPropertieMongo::get_id, id)
            .one();
        if (Objects.nonNull(entity)) {
            // 转换为VO对象
            IsfdLayupSkinPropertieMongoVo vo = MapstructUtils.convert(entity, IsfdLayupSkinPropertieMongoVo.class);
            return vo;
        }
        return null;
    }

    /**
     * 分页查询【请填写功能名称】列表
     *
     * @param bo 查询条件
     * @return 【请填写功能名称】分页列表
     */
    @Override
    public TableDataInfo<IsfdLayupSkinPropertieMongoVo> queryPageList(IsfdLayupSkinPropertieQueryBo bo) {
        // 构造返回列表
        List<IsfdLayupSkinPropertieMongo> layupSkinPropertieMongoList = new ArrayList<>();
        Integer pageNum = bo.getPageNum();
        Integer pageSize = bo.getPageSize();

        // 构造查询参数
        LambdaQueryChainWrapper<IsfdLayupSkinPropertieMongo> queryChainWrapper = this.lambdaQuery();
        queryChainWrapper
            .eq(StringUtils.isNotBlank(bo.getPlyCode()), IsfdLayupSkinPropertieMongo::getPlyCode, bo.getPlyCode())
            .eq(StringUtils.isNotBlank(bo.getMaterial()), IsfdLayupSkinPropertieMongo::getMaterial, bo.getMaterial())
            .eq(StringUtils.isNotBlank(bo.getSymmetrical()), IsfdLayupSkinPropertieMongo::getSymmetrical, bo.getSymmetrical())
            .eq(StringUtils.isNotBlank(bo.getLayerNumber()), IsfdLayupSkinPropertieMongo::getLayerNumber, bo.getLayerNumber())
            .eq(StringUtils.isNotBlank(bo.getSectionDescription()), IsfdLayupSkinPropertieMongo::getSectionDescription, bo.getSectionDescription())
            .eq(StringUtils.isNotBlank(bo.getPartDescription()), IsfdLayupSkinPropertieMongo::getPartDescription, bo.getPartDescription())
            .eq(StringUtils.isNotBlank(bo.getRemarks()), IsfdLayupSkinPropertieMongo::getRemarks, bo.getRemarks())
            .in(CollectionUtil.isNotEmpty(bo.getMetadataManagementIds()), IsfdLayupSkinPropertieMongo::getMetadataManagementId, bo.getMetadataManagementIds())
            .in(CollectionUtil.isNotEmpty(bo.getIdList()), IsfdLayupSkinPropertieMongo::get_id, bo.getIdList())
            .orderByDesc(IsfdLayupSkinPropertieMongo::getCreateTime);

        // 进行mongodb分页查询
        PageResult<IsfdLayupSkinPropertieMongo> page = this.page(queryChainWrapper, pageNum, pageSize);
        List<IsfdLayupSkinPropertieMongo> contentData = page.getContentData();

        layupSkinPropertieMongoList.addAll(contentData);
        Long total = page.getTotalSize();

        // 空集直接返回
        if (CollectionUtil.isEmpty(layupSkinPropertieMongoList)) {
            return TableDataInfo.build();
        }
        // 返回vos
        List<IsfdLayupSkinPropertieMongoVo> voList = MapstructUtils.convert(layupSkinPropertieMongoList, IsfdLayupSkinPropertieMongoVo.class);

        return TableDataInfo.buildToPageMemoryLimit(Boolean.FALSE, voList, pageNum, pageSize, total);
    }

    @Transactional
    @Override
    public Boolean save(IsfdLayupSkinPropertieMongoVo vo, LoginUser loginUser) {
        // 1. 参数校验
        checkParams(vo);

        // 2. 获取hash字段
        String hashUniqueKey = EncryptUtils.hashFields(vo.getPlyCode(), vo.getMaterial(), vo.getThickness(),
            vo.getSymmetrical(), vo.getData());

        // 3. 幂等校验
        Boolean isUpdate = checkUnique(vo, hashUniqueKey);

        // 4. 落表
        IsfdLayupSkinPropertieMongo isfdLayupSkinPropertieMongo = new IsfdLayupSkinPropertieMongo();
        vo.setHashUniqueKey(hashUniqueKey);
        vo.setUpdateBy(String.valueOf(loginUser.getUserId()));
        vo.setUpdateTime(new Date().toString());
        // 判断是新增业务还是修改业务
        if (!isUpdate) {
            vo.setCreateBy(String.valueOf(loginUser.getUserId()));
            vo.setCreateTime(new Date().toString());

            // 如果是新增，需要记录record导入信息
            IsfdDatabaseModelConfig modelConfig = isfdDatabaseModelConfigMapper.selectModelByModelName("铺层库-蒙皮属性库");
            IsfdDatabaseDataImportRecordBo recordBo = new IsfdDatabaseDataImportRecordBo();
            IsfdBusinessDatabaseRefVo isfdBusinessDatabaseRefVo = isfdBusinessDatabaseRefMapper.selectDataBymodelId(modelConfig.getId());
            recordBo.setSceneId(isfdBusinessDatabaseRefVo.getSceneId());
            recordBo.setSystemId(isfdBusinessDatabaseRefVo.getSystemId());
            recordBo.setModelId(isfdBusinessDatabaseRefVo.getParentModelId());
            recordBo.setModelName(modelConfig.getModelName());
            recordBo.setTableName(modelConfig.getTableName());
            recordBo.setDatabaseTypeId(isfdBusinessDatabaseRefVo.getDatabaseTypeId());
            recordBo.setDataQuantity(1);

            String tableName = modelConfig.getTableName();
            Map<String, Integer> tableNameAndDataQuantity = new HashMap<>();
            tableNameAndDataQuantity.put(tableName, 1);
            IsfdDatabaseDataImportRecordBo importRecordBo = importRecordService.createImportRecord(recordBo, IsfdImportMethodEnum.SITE, tableName, tableNameAndDataQuantity, loginUser);
            IsfdDatabaseDataImportRecord importRecord = new IsfdDatabaseDataImportRecord();
            MapstructUtils.convert(importRecordBo, importRecord);
            vo.setImportRecord(importRecord);
        }
        BeanUtils.copyProperties(vo, isfdLayupSkinPropertieMongo);
        this.saveOrUpdate(isfdLayupSkinPropertieMongo);
        return Boolean.TRUE;
    }


    private void checkParams(IsfdLayupSkinPropertieMongoVo vo) {
        if (StringUtils.isBlank(vo.getPlyCode())) {
            throw new BaseException("铺层代码不能为空，请确认后重试！");
        }
        if (StringUtils.isBlank(vo.getMaterial())) {
            throw new BaseException("材料编号不能为空，请确认后重试！");
        }
        if (vo.getThickness() == null) {
            throw new BaseException("thickness不能为空，请确认后重试！");
        }
        if (vo.getSymmetrical() == null) {
            throw new BaseException("是否对称不能为空，请确认后重试！");
        }
        if (StringUtils.isBlank(vo.getData())) {
            throw new BaseException("铺层序列不能为空，请确认后重试！");
        }
    }


    @Override
    public Boolean checkUnique(IsfdLayupSkinPropertieMongoVo vo, String hashUniqueKey) {
        Boolean isUpdate = Boolean.FALSE;
        String id = vo.get_id();
        if (!StringUtils.isNotEmpty(id)) {
            IsfdLayupSkinPropertieMongo oldIsfdLayupSkinPropertie = this.lambdaQuery()
                .eq(IsfdLayupSkinPropertieMongo::getHashUniqueKey, hashUniqueKey)
                .one();
            if (oldIsfdLayupSkinPropertie != null) {
                throw new BaseException("已经存在相同属性蒙皮，不可重复存入，请确认入参后重试！");
            }
        } else {
            IsfdLayupSkinPropertieMongoVo isfdLayupSkinPropertieMongoVo = queryById(id);
            if (Objects.isNull(isfdLayupSkinPropertieMongoVo)) {
                throw new BaseException("修改失败，数据不存在，请确认id后重试！");
            }
            String hashUniqueKeyForDb = isfdLayupSkinPropertieMongoVo.getHashUniqueKey();
            if (hashUniqueKey.equals(hashUniqueKeyForDb)) {
                throw new BaseException("已经存在相同属性蒙皮，不可重复存入，请确认入参后重试！");
            }
            isUpdate = Boolean.TRUE;
        }
        return isUpdate;
    }

    /**
     * 校验并批量删除【请填写功能名称】信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        for (String id : ids) {
            // 查询铺层材料并删除
            IsfdLayupSkinPropertieMongoVo isfdLayupSkinPropertieMongoVo = queryById(id);
            // 删除铺层
            if (Objects.nonNull(isfdLayupSkinPropertieMongoVo)) {
                LambdaUpdateChainWrapper<IsfdLayupSkinPropertieMongo> updateChainWrapper = this.lambdaUpdate();
                updateChainWrapper.eq(IsfdLayupSkinPropertieMongo::get_id, id);
                this.remove(updateChainWrapper);
            } else {
                throw new BaseException("删除失败，数据不存在，请确认id后重试！");
            }
        }
        return Boolean.TRUE;
    }

    @Override
    public void export(IsfdLayupSkinPropertieQueryBo queryBo, HttpServletResponse response) {
        queryBo.setPageNum(1);
        queryBo.setPageSize(999999999);
        TableDataInfo<IsfdLayupSkinPropertieMongoVo> isfdLayupSkinPropertieMongoVoTable = queryPageList(queryBo);
        List<IsfdLayupSkinPropertieMongoVo> isfdLayupSkinPropertieMongoVoList = isfdLayupSkinPropertieMongoVoTable.getRows();

        // data字段需要重新构造导出的列
        // 确定最大的PLY列数
        int maxPly = isfdLayupSkinPropertieMongoVoList.stream()
            .mapToInt(vo -> vo.getData().split(",").length)
            .max()
            .orElse(0);

        // 构建动态表头：原导出字段 + PLY1到PLYN
        List<String> headerList = new ArrayList<>();
        headerList.add("铺层代码");
        headerList.add("材料");
        headerList.add("单层厚度");
        headerList.add("是否对称铺层");
        for (int i = 1; i <= maxPly; i++) {
            headerList.add("PLY" + i);
        }

        // 转换数据为Map列表
        List<Map<String, Object>> dataList = new ArrayList<>();
        for (IsfdLayupSkinPropertieMongoVo vo : isfdLayupSkinPropertieMongoVoList) {
            Map<String, Object> rowMap = new HashMap<>();
            // 添加原导出字段
            rowMap.put("铺层代码", vo.getPlyCode());
            rowMap.put("材料", vo.getMaterial());
            rowMap.put("单层厚度", vo.getThickness());
            rowMap.put("是否对称铺层", vo.getSymmetrical());
            // 拆分data字段到PLY列
            String[] plyValues = vo.getData().split(",");
            for (int i = 0; i < maxPly; i++) {
                String plyKey = "PLY" + (i + 1);
                rowMap.put(plyKey, i < plyValues.length ? plyValues[i] : "");
            }
            dataList.add(rowMap);
        }

        ExcelUtil.exportExcelReBuildHeader("【铺层库蒙皮属性】", headerList, dataList, response);
    }


}
